From 559c750b277ebc8aaee130f6915d803a8d00db64 Mon Sep 17 00:00:00 2001 From: tsteven4 <13596209+tsteven4@users.noreply.github.com> Date: Thu, 21 Nov 2019 09:37:25 -0700 Subject: [PATCH] use Qt containers for format/style/filter vecs. --- defs.h | 11 +- filter_vecs.cc | 294 +++++++++++++++++++--------------------- filterdefs.h | 2 +- internal_styles.cc | 7 +- mkstyle.sh | 15 ++- vecs.cc | 325 ++++++++++++++++++++------------------------- 6 files changed, 297 insertions(+), 357 deletions(-) diff --git a/defs.h b/defs.h index 67ac6a90e..ebe6149b1 100644 --- a/defs.h +++ b/defs.h @@ -42,6 +42,7 @@ #include // for QString #include // for QStringRef #include // for QTextCodec +#include // for QVector #include // for CaseInsensitive #include // for foreach @@ -985,7 +986,7 @@ void setshort_is_utf8(short_handle h, int is_utf8); #define ARG_NOMINMAX NULL, NULL #define ARG_TERMINATOR {0, 0, 0, 0, 0, ARG_NOMINMAX, NULL} -typedef struct arglist { +struct arglist_t { const char* argstring; char** argval; const char* helpstring; @@ -994,7 +995,7 @@ typedef struct arglist { const char* minvalue; /* minimum value for numeric options */ const char* maxvalue; /* maximum value for numeric options */ char* argvalptr; /* !!! internal helper. Not used in definitions !!! */ -} arglist_t; +}; typedef enum { ff_type_file = 1, /* normal format: useful to a GUI. */ @@ -1055,11 +1056,11 @@ typedef struct ff_vecs { const char* name; /* dyn. initialized by find_vec */ } ff_vecs_t; -typedef struct style_vecs { +struct style_vecs_t { const char* name; const char* style_buf; -} style_vecs_t; -extern style_vecs_t style_list[]; +}; +extern const QVector style_list; [[noreturn]] void fatal(const char*, ...) PRINTFLIKE(1, 2); void is_fatal(int condition, const char*, ...) PRINTFLIKE(2, 3); diff --git a/filter_vecs.cc b/filter_vecs.cc index c81a26de2..00476b6d8 100644 --- a/filter_vecs.cc +++ b/filter_vecs.cc @@ -42,16 +42,22 @@ #include "validate.h" #include "gbversion.h" #include "inifile.h" -#include -#include -#include -#include // qsort -typedef struct { +#include // for QList +#include // for QString +#include // for QStringList +#include // for QVector<>::iterator, QVector +#include // for CaseInsensitive + +#include // for sort +#include // for printf +#include // for strchr + +struct fl_vecs_t { Filter* vec; const char* name; const char* desc; -} fl_vecs_t; +}; ArcDistanceFilter arcdist; BendFilter bend; @@ -74,93 +80,93 @@ ValidateFilter validate; static -fl_vecs_t filter_vec_list[] = { +const QVector filter_vec_list = { #if FILTERS_ENABLED - { - &arcdist, - "arc", - "Include Only Points Within Distance of Arc", - }, - { - &bend, - "bend", - "Add points before and after bends in routes" - }, - { - &discard, - "discard", - "Remove unreliable points with high hdop or vdop" - }, - { - &duplicate, - "duplicate", - "Remove Duplicates", - }, - { - &interpolate, - "interpolate", - "Interpolate between trackpoints" - }, - { - &nukedata, - "nuketypes", - "Remove all waypoints, tracks, or routes" - }, - { - &polygon, - "polygon", - "Include Only Points Inside Polygon", - }, - { - &position, - "position", - "Remove Points Within Distance", - }, - { - &radius, - "radius", - "Include Only Points Within Radius", - }, - { - &routesimple, - "simplify", - "Simplify routes", - }, - { - &sort, - "sort", - "Rearrange waypoints, routes and/or tracks by resorting", - }, - { - &stackfilt, - "stack", - "Save and restore waypoint lists" - }, - { - &reverse_route, - "reverse", - "Reverse stops within routes", - }, - { - &trackfilter, - "track", - "Manipulate track lists" - }, - { - &transform, - "transform", - "Transform waypoints into a route, tracks into routes, ..." - }, - { - &height, - "height", - "Manipulate altitudes" - }, - { - &swapdata, - "swap", - "Swap latitude and longitude of all loaded points" - }, + { + &arcdist, + "arc", + "Include Only Points Within Distance of Arc", + }, + { + &bend, + "bend", + "Add points before and after bends in routes" + }, + { + &discard, + "discard", + "Remove unreliable points with high hdop or vdop" + }, + { + &duplicate, + "duplicate", + "Remove Duplicates", + }, + { + &interpolate, + "interpolate", + "Interpolate between trackpoints" + }, + { + &nukedata, + "nuketypes", + "Remove all waypoints, tracks, or routes" + }, + { + &polygon, + "polygon", + "Include Only Points Inside Polygon", + }, + { + &position, + "position", + "Remove Points Within Distance", + }, + { + &radius, + "radius", + "Include Only Points Within Radius", + }, + { + &routesimple, + "simplify", + "Simplify routes", + }, + { + &sort, + "sort", + "Rearrange waypoints, routes and/or tracks by resorting", + }, + { + &stackfilt, + "stack", + "Save and restore waypoint lists" + }, + { + &reverse_route, + "reverse", + "Reverse stops within routes", + }, + { + &trackfilter, + "track", + "Manipulate track lists" + }, + { + &transform, + "transform", + "Transform waypoints into a route, tracks into routes, ..." + }, + { + &height, + "height", + "Manipulate altitudes" + }, + { + &swapdata, + "swap", + "Swap latitude and longitude of all loaded points" + }, { &validate, "validate", @@ -172,43 +178,33 @@ fl_vecs_t filter_vec_list[] = { &trackfilter, "track", "Manipulate track lists" - }, -#endif - { - nullptr, - nullptr, - nullptr } +#endif }; Filter* find_filter_vec(const char* const vecname, const char** opts) { - fl_vecs_t* vec = filter_vec_list; - char* v = xstrdup(vecname); - QString svecname = QString(v).split(",")[0]; + const QString svecname = QString(vecname).split(',').at(0); int found = 0; - while (vec->vec) { - arglist_t* ap; - - if (svecname.compare(vec->name, Qt::CaseInsensitive)) { - vec++; + for (const auto& vec : filter_vec_list) { + if (svecname.compare(vec.name, Qt::CaseInsensitive)) { continue; } /* step 1: initialize by inifile or default values */ - struct arglist* args = vec->vec->get_args(); + arglist_t* args = vec.vec->get_args(); if (args) { - for (ap = args; ap->argstring; ap++) { - QString qtemp = inifile_readstr(global_opts.inifile, vec->name, ap->argstring); + for (auto ap = args; ap->argstring; ap++) { + QString qtemp = inifile_readstr(global_opts.inifile, vec.name, ap->argstring); if (qtemp.isNull()) { qtemp = inifile_readstr(global_opts.inifile, "Common filter settings", ap->argstring); } if (qtemp.isNull()) { - assign_option(vec->name, ap, ap->defaultvalue); + assign_option(vec.name, ap, ap->defaultvalue); } else { - assign_option(vec->name, ap, CSTR(qtemp)); + assign_option(vec.name, ap, CSTR(qtemp)); } } } @@ -219,11 +215,11 @@ find_filter_vec(const char* const vecname, const char** opts) *opts = res+1; if (args) { - for (ap = args; ap->argstring; ap++) { + for (auto ap = args; ap->argstring; ap++) { char* opt = get_option(*opts, ap->argstring); if (opt) { found = 1; - assign_option(vec->name, ap, opt); + assign_option(vec.name, ap, opt); xfree(opt); } } @@ -232,25 +228,23 @@ find_filter_vec(const char* const vecname, const char** opts) *opts = nullptr; } if (opts && opts[0] && !found) { - warning("'%s' is an unknown option to %s.\n", *opts, vec->name); + warning("'%s' is an unknown option to %s.\n", *opts, vec.name); } if (global_opts.debug_level >= 1) { - disp_vec_options(vec->name, args); + disp_vec_options(vec.name, args); } - xfree(v); - return vec->vec; + return vec.vec; } - xfree(v); return nullptr; } void free_filter_vec(Filter* filter) { - struct arglist* args = filter->get_args(); + arglist_t* args = filter->get_args(); if (args) { for (arglist_t* ap = args; ap->argstring; ap++) { @@ -265,25 +259,21 @@ free_filter_vec(Filter* filter) void init_filter_vecs() { - fl_vecs_t* vec = filter_vec_list; - while (vec->vec) { - struct arglist* args = vec->vec->get_args(); + for (const auto& vec : filter_vec_list) { + arglist_t* args = vec.vec->get_args(); if (args) { for (arglist_t* ap = args; ap->argstring; ap++) { ap->argvalptr = nullptr; } } - vec++; } } void exit_filter_vecs() { - fl_vecs_t* vec = filter_vec_list; - while (vec->vec) { - (vec->vec->exit)(); - vec++; + for (const auto& vec : filter_vec_list) { + (vec.vec->exit)(); } } @@ -294,10 +284,10 @@ exit_filter_vecs() void disp_filter_vecs() { - for (fl_vecs_t* vec = filter_vec_list; vec->vec; vec++) { + for (const auto& vec : filter_vec_list) { printf(" %-20.20s %-50.50s\n", - vec->name, vec->desc); - struct arglist* args = vec->vec->get_args(); + vec.name, vec.desc); + arglist_t* args = vec.vec->get_args(); for (arglist_t* ap = args; ap && ap->argstring; ap++) { if (!(ap->argtype & ARGTYPE_HIDDEN)) printf(" %-18.18s %-.50s %s\n", @@ -310,13 +300,13 @@ disp_filter_vecs() void disp_filter_vec(const char* vecname) { - for (fl_vecs_t* vec = filter_vec_list; vec->vec; vec++) { - if (case_ignore_strcmp(vec->name, vecname)) { + for (const auto& vec : filter_vec_list) { + if (case_ignore_strcmp(vec.name, vecname)) { continue; } printf(" %-20.20s %-50.50s\n", - vec->name, vec->desc); - struct arglist* args = vec->vec->get_args(); + vec.name, vec.desc); + arglist_t* args = vec.vec->get_args(); for (arglist_t* ap = args; ap && ap->argstring; ap++) { if (!(ap->argtype & ARGTYPE_HIDDEN)) printf(" %-18.18s %-.50s %s\n", @@ -326,34 +316,31 @@ disp_filter_vec(const char* vecname) } } -static signed int -alpha(const void* a, const void* b) +static bool +alpha(const fl_vecs_t& a, const fl_vecs_t& b) { - const fl_vecs_t* const ap = (const fl_vecs_t*) a; - const fl_vecs_t* const bp = (const fl_vecs_t*) b; - - return case_ignore_strcmp(ap->desc, bp->desc); + return case_ignore_strcmp(a.desc, b.desc) < 0; } static -void disp_help_url(const fl_vecs_t* vec, arglist_t* arg) +void disp_help_url(const fl_vecs_t& vec, arglist_t* arg) { - printf("\t" WEB_DOC_DIR "/fmt_%s.html", vec->name); + printf("\t" WEB_DOC_DIR "/fmt_%s.html", vec.name); if (arg) { - printf("#fmt_%s_o_%s",vec->name, arg->argstring); + printf("#fmt_%s_o_%s",vec.name, arg->argstring); } } static void -disp_v1(const fl_vecs_t* vec) +disp_v1(const fl_vecs_t& vec) { disp_help_url(vec, nullptr); printf("\n"); - struct arglist* args = vec->vec->get_args(); + arglist_t* args = vec.vec->get_args(); for (arglist_t* ap = args; ap && ap->argstring; ap++) { if (!(ap->argtype & ARGTYPE_HIDDEN)) { printf("option\t%s\t%s\t%s\t%s\t%s\t%s\t%s", - vec->name, + vec.name, ap->argstring, ap->helpstring, name_option(ap->argtype), @@ -374,22 +361,17 @@ disp_v1(const fl_vecs_t* vec) void disp_filters(int version) { - fl_vecs_t* vec; - - qsort(filter_vec_list, - sizeof(filter_vec_list) / sizeof(filter_vec_list[0]) - 1, - sizeof(filter_vec_list[0]), - alpha); - + auto sorted_filter_vec_list = filter_vec_list; + std::sort(sorted_filter_vec_list.begin(), sorted_filter_vec_list.end(), alpha); switch (version) { case 0: case 1: - for (vec = filter_vec_list; vec->vec; vec++) { + for (const auto& vec : sorted_filter_vec_list) { if (version == 0) { - printf("%s\t%s\n", vec->name, vec->desc); + printf("%s\t%s\n", vec.name, vec.desc); } else { - printf("%s\t%s", vec->name, vec->desc); + printf("%s\t%s", vec.name, vec.desc); disp_v1(vec); } } diff --git a/filterdefs.h b/filterdefs.h index 281c86ddf..ef1f9cf1b 100644 --- a/filterdefs.h +++ b/filterdefs.h @@ -44,7 +44,7 @@ typedef struct filter_vecs { filter_process f_process; filter_deinit f_deinit; filter_exit f_exit; - struct arglist* args; + arglist_t* args; } filter_vecs_t; Filter* find_filter_vec(const char* const, const char**); diff --git a/internal_styles.cc b/internal_styles.cc index 990323463..9093fe24c 100644 --- a/internal_styles.cc +++ b/internal_styles.cc @@ -1,6 +1,7 @@ /* This file is machine-generated from the contents of style/ */ /* by mkstyle.sh. Editing it by hand is an exceedingly bad idea. */ +#include #include "defs.h" #if CSVFMTS_ENABLED static char arc[] = @@ -1489,9 +1490,7 @@ static char xmapwpt[] = "IFIELD IGNORE, \"\", \"%-.31s\"\n" "IFIELD DESCRIPTION, \"\", \"%-.78s\"\n" ; -style_vecs_t style_list[] = {{ "xmapwpt", xmapwpt } , { "xmap2006", xmap2006 } , { "xmap", xmap } , { "tomtom_itn_places", tomtom_itn_places } , { "tomtom_itn", tomtom_itn } , { "tomtom_asc", tomtom_asc } , { "tabsep", tabsep } , { "saplus", saplus } , { "s_and_t", s_and_t } , { "ricoh", ricoh } , { "openoffice", openoffice } , { "nima", nima } , { "navigonwpt", navigonwpt } , { "mxf", mxf } , { "motoactv", motoactv } , { "mapconverter", mapconverter } , { "mainnav", mainnav } , { "land_air_sea", land_air_sea } , { "kompass_wp", kompass_wp } , { "kompass_tk", kompass_tk } , { "igoprimo_poi", igoprimo_poi } , { "igo2008_poi", igo2008_poi } , { "iblue757", iblue757 } , { "iblue747", iblue747 } , { "gpsman", gpsman } , { "gpsdrivetrack", gpsdrivetrack } , { "gpsdrive", gpsdrive } , { "geonet", geonet } , { "garmin_poi", garmin_poi } , { "garmin_g1000", garmin_g1000 } , { "garmin301", garmin301 } , { "fugawi", fugawi } , { "flysight", flysight } , { "dna", dna } , { "custom", custom } , { "cup", cup } , { "csv", csv } , { "cambridge", cambridge } , { "arc", arc } , {nullptr,nullptr}}; -size_t nstyles = 39; +const QVector style_list = {{ "xmapwpt", xmapwpt }, { "xmap2006", xmap2006 }, { "xmap", xmap }, { "tomtom_itn_places", tomtom_itn_places }, { "tomtom_itn", tomtom_itn }, { "tomtom_asc", tomtom_asc }, { "tabsep", tabsep }, { "saplus", saplus }, { "s_and_t", s_and_t }, { "ricoh", ricoh }, { "openoffice", openoffice }, { "nima", nima }, { "navigonwpt", navigonwpt }, { "mxf", mxf }, { "motoactv", motoactv }, { "mapconverter", mapconverter }, { "mainnav", mainnav }, { "land_air_sea", land_air_sea }, { "kompass_wp", kompass_wp }, { "kompass_tk", kompass_tk }, { "igoprimo_poi", igoprimo_poi }, { "igo2008_poi", igo2008_poi }, { "iblue757", iblue757 }, { "iblue747", iblue747 }, { "gpsman", gpsman }, { "gpsdrivetrack", gpsdrivetrack }, { "gpsdrive", gpsdrive }, { "geonet", geonet }, { "garmin_poi", garmin_poi }, { "garmin_g1000", garmin_g1000 }, { "garmin301", garmin301 }, { "fugawi", fugawi }, { "flysight", flysight }, { "dna", dna }, { "custom", custom }, { "cup", cup }, { "csv", csv }, { "cambridge", cambridge }, { "arc", arc }}; #else /* CSVFMTS_ENABLED */ -style_vecs_t style_list[] = {{nullptr,nullptr}}; -size_t nstyles = 0; +const QVector style_list; #endif /* CSVFMTS_ENABLED */ diff --git a/mkstyle.sh b/mkstyle.sh index 7ce3b28fc..5ff0b5001 100755 --- a/mkstyle.sh +++ b/mkstyle.sh @@ -24,24 +24,25 @@ else exit 1 fi +echo "#include " echo "#include \"defs.h\"" echo "#if CSVFMTS_ENABLED" -nstyles="0" for i in `dirname $0`/style/*.style do A=`basename $i | sed "s/.style$//"` [ $A = "README" ] && continue [ $A = "custom.style" ] && continue - ALIST="{ \"$A\", $A } , $ALIST" + if [ "x${ALIST}" = "x" ]; then + ALIST="{ \"$A\", $A }" + else + ALIST="{ \"$A\", $A }, $ALIST" + fi echo "static char $A[] =" $SED 's/\\/\\\\/;s/"/\\"/g;s/^\(.\)/"\1/g;s/\(.\)$/\1\\n"/g;s/^\(.\)/ \1/' $i echo " ;" - nstyles=`expr $nstyles + 1`; done -echo "style_vecs_t style_list[] = {$ALIST {nullptr,nullptr}};" -echo "size_t nstyles = $nstyles;" +echo "const QVector style_list = {$ALIST};" echo "#else /* CSVFMTS_ENABLED */" -echo "style_vecs_t style_list[] = {{nullptr,nullptr}};" -echo "size_t nstyles = 0;" +echo "const QVector style_list;" echo "#endif /* CSVFMTS_ENABLED */" diff --git a/vecs.cc b/vecs.cc index 2d5d0889f..578f23264 100644 --- a/vecs.cc +++ b/vecs.cc @@ -19,24 +19,30 @@ */ -#include "defs.h" -#include "csv_util.h" -#include "gbversion.h" -#include "inifile.h" -#include "xcsv.h" #include -#include -#include // qsort +#include + +#include // for sort +#include // for printf, putchar, sscanf, size_t +#include +#include // for strchr, strtok, memset, strlen +#include // for isdigit + +#include "defs.h" +#include "gbversion.h" // for WEB_DOC_DIR +#include "inifile.h" // for inifile_readstr +#include "xcsv.h" // for XcsvFile, xcsv_file, xcsv_read_internal_style, xcsv_setup_internal_style + #define MYNAME "vecs.c" -typedef struct { +struct vecs_t { ff_vecs_t* vec; const char* name; QString desc; QString extensions; // list of possible extensions separated by '/', first is output default for GUI. const char* parent; -} vecs_t; +}; extern ff_vecs_t an1_vecs; extern ff_vecs_t bcr_vecs; @@ -182,7 +188,7 @@ extern ff_vecs_t f90g_track_vecs; extern ff_vecs_t mapfactor_vecs; static -vecs_t vec_list[] = { +const QVector vec_list = { #if CSVFMTS_ENABLED /* XCSV must be the first entry in this table. */ { @@ -1085,31 +1091,22 @@ vecs_t vec_list[] = { "GlobalSat GH625XT GPS training watch", nullptr, nullptr, - }, -#endif // MAXIMAL_ENABLED - { - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, } +#endif // MAXIMAL_ENABLED }; void init_vecs() { - vecs_t* vec = vec_list; - while (vec->vec) { - if (vec->vec->args) { - for (auto ap = vec->vec->args; ap->argstring; ap++) { + for (const auto& vec : vec_list) { + if (vec.vec->args) { + for (auto ap = vec.vec->args; ap->argstring; ap++) { ap->argvalptr = nullptr; if (ap->argval) { *ap->argval = nullptr; } } } - vec++; } } @@ -1122,13 +1119,12 @@ is_integer(const char* c) void exit_vecs() { - vecs_t* vec = vec_list; - while (vec->vec) { - if (vec->vec->exit) { - (*vec->vec->exit)(); + for (const auto& vec : vec_list) { + if (vec.vec->exit) { + (*vec.vec->exit)(); } - if (vec->vec->args) { - for (auto ap = vec->vec->args; ap->argstring; ap++) { + if (vec.vec->args) { + for (auto ap = vec.vec->args; ap->argstring; ap++) { if (ap->defaultvalue && (ap->argtype == ARGTYPE_INT) && ! is_integer(ap->defaultvalue)) { @@ -1140,7 +1136,6 @@ exit_vecs() } } } - vec++; } } @@ -1250,8 +1245,6 @@ disp_vec_options(const char* vecname, arglist_t* ap) ff_vecs_t* find_vec(const char* vecname, const char** opts) { - vecs_t* vec = vec_list; - style_vecs_t* svec = style_list; char* v = xstrdup(vecname); char* svecname = strtok(v, ","); int found = 0; @@ -1260,9 +1253,8 @@ find_vec(const char* vecname, const char** opts) fatal("A format name is required.\n"); } - while (vec->vec) { - if (case_ignore_strcmp(svecname, vec->name)) { - vec++; + for (const auto& vec : vec_list) { + if (case_ignore_strcmp(svecname, vec.name)) { continue; } @@ -1273,8 +1265,8 @@ find_vec(const char* vecname, const char** opts) *opts = nullptr; } - if (vec->vec->args) { - for (auto ap = vec->vec->args; ap->argstring; ap++) { + if (vec.vec->args) { + for (auto ap = vec.vec->args; ap->argstring; ap++) { if (res) { const char* opt = get_option(*opts, ap->argstring); if (opt) { @@ -1284,31 +1276,31 @@ find_vec(const char* vecname, const char** opts) continue; } } - QString qopt = inifile_readstr(global_opts.inifile, vec->name, ap->argstring); + QString qopt = inifile_readstr(global_opts.inifile, vec.name, ap->argstring); if (qopt.isNull()) { qopt = inifile_readstr(global_opts.inifile, "Common format settings", ap->argstring); } if (qopt.isNull()) { - assign_option(vec->name, ap, ap->defaultvalue); + assign_option(vec.name, ap, ap->defaultvalue); } else { - assign_option(vec->name, ap, CSTR(qopt)); + assign_option(vec.name, ap, CSTR(qopt)); } } } if (opts && opts[0] && !found) { - warning("'%s' is an unknown option to %s.\n", *opts, vec->name); + warning("'%s' is an unknown option to %s.\n", *opts, vec.name); } if (global_opts.debug_level >= 1) { - disp_vec_options(vec->name, vec->vec->args); + disp_vec_options(vec.name, vec.vec->args); } #if CSVFMTS_ENABLED // xcsv_setup_internal_style( NULL ); #endif // CSVFMTS_ENABLED xfree(v); - vec->vec->name = vec->name; /* needed for session information */ - return vec->vec; + vec.vec->name = vec.name; /* needed for session information */ + return vec.vec; } @@ -1316,9 +1308,8 @@ find_vec(const char* vecname, const char** opts) * Didn't find it in the table of "real" file types, so plan B * is to search the list of xcsv styles. */ - while (svec->name) { - if (case_ignore_strcmp(svecname, svec->name)) { - svec++; + for (const auto& svec : style_list) { + if (case_ignore_strcmp(svecname, svec.name)) { continue; } @@ -1340,31 +1331,31 @@ find_vec(const char* vecname, const char** opts) continue; } } - QString qopt = inifile_readstr(global_opts.inifile, svec->name, ap->argstring); + QString qopt = inifile_readstr(global_opts.inifile, svec.name, ap->argstring); if (qopt.isNull()) { qopt = inifile_readstr(global_opts.inifile, "Common format settings", ap->argstring); } if (qopt.isNull()) { - assign_option(svec->name, ap, ap->defaultvalue); + assign_option(svec.name, ap, ap->defaultvalue); } else { - assign_option(svec->name, ap, CSTR(qopt)); + assign_option(svec.name, ap, CSTR(qopt)); } } } if (opts && opts[0] && !found) { - warning("'%s' is an unknown option to %s.\n", *opts, svec->name); + warning("'%s' is an unknown option to %s.\n", *opts, svec.name); } if (global_opts.debug_level >= 1) { - disp_vec_options(svec->name, vec_list[0].vec->args); + disp_vec_options(svec.name, vec_list[0].vec->args); } #if CSVFMTS_ENABLED - xcsv_setup_internal_style(svec->style_buf); + xcsv_setup_internal_style(svec.style_buf); #endif // CSVFMTS_ENABLED xfree(v); - vec_list[0].vec->name = svec->name; /* needed for session information */ + vec_list[0].vec->name = svec.name; /* needed for session information */ return vec_list[0].vec; } @@ -1424,14 +1415,10 @@ get_option(const char* iarglist, const char* argname) * Display the available formats in a format that's easy for humans to * parse for help on available command line options. */ -static signed int -alpha(const void* a, const void* b) +static bool +alpha(const vecs_t& a, const vecs_t& b) { - - const vecs_t* const* ap = (const vecs_t *const*) a; - const vecs_t* const* bp = (const vecs_t *const*) b; - - return case_ignore_strcmp((*ap)->desc , (*bp)->desc); + return case_ignore_strcmp(a.desc, b.desc) < 0; } /* @@ -1439,79 +1426,63 @@ alpha(const void* a, const void* b) * alphabetically. Returns an allocated copy of a style_vecs_array * that's populated and sorted. */ -vecs_t** -sort_and_unify_vecs(int* ctp) +QVector +sort_and_unify_vecs() { - size_t vc; - vecs_t** svp; -#if CSVFMTS_ENABLED -#endif - int i = 0; - - /* Get a count from both the vec (normal) and the svec (csv) lists */ - -#if CSVFMTS_ENABLED - extern size_t nstyles; - vc = sizeof vec_list / sizeof vec_list[0] - 1 + nstyles; -#else - vc = sizeof vec_list / sizeof vec_list[0] - 1; -#endif // CSVFMTS_ENABLED - - - svp = (vecs_t**)xcalloc(vc, sizeof(style_vecs_t*)); + QVector svp; + svp.reserve(vec_list.size() + style_list.size()); /* Normal vecs are easy; populate the first part of the array. */ - for (vecs_t* vec = vec_list; vec->vec; vec++, i++) { - svp[i] = vec; - if (svp[i]->parent == nullptr) { - svp[i]->parent = svp[i]->name; + for (const auto& vec : vec_list) { + vecs_t uvec = vec; + if (uvec.parent == nullptr) { + uvec.parent = uvec.name; } + svp.append(uvec); } -#if CSVFMTS_ENABLED /* Walk the style list, parse the entries, dummy up a "normal" vec */ - for (style_vecs_t* svec = style_list; svec->name; svec++, i++) { - xcsv_read_internal_style(svec->style_buf); - svp[i] = new vecs_t; - svp[i]->name = svec->name; - svp[i]->vec = (ff_vecs_t*) xmalloc(sizeof(*svp[i]->vec)); - svp[i]->extensions = xcsv_file.extension; - *svp[i]->vec = *vec_list[0].vec; /* Inherits xcsv opts */ + for (const auto& svec : style_list) { + xcsv_read_internal_style(svec.style_buf); + vecs_t uvec; + uvec.name = svec.name; + uvec.vec = new ff_vecs_t; /* LEAK */ + uvec.extensions = xcsv_file.extension; + *uvec.vec = *vec_list[0].vec; /* Inherits xcsv opts */ /* Reset file type to inherit ff_type from xcsv for everything * except the xcsv format itself, which we leave as "internal" */ - if (case_ignore_strcmp(svec->name, "xcsv")) { - svp[i]->vec->type = xcsv_file.type; + if (case_ignore_strcmp(svec.name, "xcsv")) { + uvec.vec->type = xcsv_file.type; /* Skip over the first help entry for all but the * actual 'xcsv' format - so we don't expose the * 'full path to xcsv style file' argument to any * GUIs for an internal format. */ - svp[i]->vec->args++; + uvec.vec->args++; } - memset(&svp[i]->vec->cap, 0, sizeof(svp[i]->vec->cap)); + memset(&uvec.vec->cap, 0, sizeof(uvec.vec->cap)); switch (xcsv_file.datatype) { case unknown_gpsdata: case wptdata: - svp[i]->vec->cap[ff_cap_rw_wpt] = (ff_cap)(ff_cap_read | ff_cap_write); + uvec.vec->cap[ff_cap_rw_wpt] = (ff_cap)(ff_cap_read | ff_cap_write); break; case trkdata: - svp[i]->vec->cap[ff_cap_rw_trk] = (ff_cap)(ff_cap_read | ff_cap_write); + uvec.vec->cap[ff_cap_rw_trk] = (ff_cap)(ff_cap_read | ff_cap_write); break; case rtedata: - svp[i]->vec->cap[ff_cap_rw_rte] = (ff_cap)(ff_cap_read | ff_cap_write); + uvec.vec->cap[ff_cap_rw_rte] = (ff_cap)(ff_cap_read | ff_cap_write); break; default: ; } - svp[i]->desc = xcsv_file.description; - svp[i]->parent = "xcsv"; + uvec.desc = xcsv_file.description; + uvec.parent = "xcsv"; + svp.append(uvec); } -#endif // CSVFMTS_ENABLED /* Now that we have everything in an array, alphabetize them */ - qsort(svp, vc, sizeof(*svp), alpha); + std::sort(svp.begin(), svp.end(), alpha); - *ctp = i; return svp; } @@ -1520,15 +1491,13 @@ sort_and_unify_vecs(int* ctp) void disp_vecs() { - int vc; - - vecs_t** svp = sort_and_unify_vecs(&vc); - for (int i = 0; ivec->type == ff_type_internal) { + const auto svp = sort_and_unify_vecs(); + for (const auto& vec : svp) { + if (vec.vec->type == ff_type_internal) { continue; } - printf(VEC_FMT, svp[i]->name, CSTR(svp[i]->desc)); - for (auto ap = svp[i]->vec->args; ap && ap->argstring; ap++) { + printf(VEC_FMT, vec.name, CSTR(vec.desc)); + for (auto ap = vec.vec->args; ap && ap->argstring; ap++) { if (!(ap->argtype & ARGTYPE_HIDDEN)) printf(" %-18.18s %s%-.50s %s\n", ap->argstring, @@ -1538,22 +1507,19 @@ disp_vecs() (ap->argtype & ARGTYPE_REQUIRED)?"(required)":""); } } - xfree(svp); } void disp_vec(const char* vecname) { - int vc; - - vecs_t** svp = sort_and_unify_vecs(&vc); - for (int i = 0; iname, vecname)) { + const auto svp = sort_and_unify_vecs(); + for (const auto& vec : svp) { + if (case_ignore_strcmp(vec.name, vecname)) { continue; } - printf(VEC_FMT, svp[i]->name, CSTR(svp[i]->desc)); - for (auto ap = svp[i]->vec->args; ap && ap->argstring; ap++) { + printf(VEC_FMT, vec.name, CSTR(vec.desc)); + for (auto ap = vec.vec->args; ap && ap->argstring; ap++) { if (!(ap->argtype & ARGTYPE_HIDDEN)) printf(" %-18.18s %s%-.50s %s\n", ap->argstring, @@ -1563,7 +1529,6 @@ disp_vec(const char* vecname) (ap->argtype & ARGTYPE_REQUIRED)?"(required)":""); } } - xfree(svp); } /* @@ -1595,7 +1560,7 @@ disp_v1(ff_type t) static void disp_v2(ff_vecs_t* v) { - for (auto &i : v->cap) { + for (auto& i : v->cap) { putchar((i & ff_cap_read) ? 'r' : '-'); putchar((i & ff_cap_write) ? 'w' : '-'); } @@ -1622,24 +1587,24 @@ name_option(uint32_t type) } static -void disp_help_url(const vecs_t* vec, arglist_t* arg) +void disp_help_url(const vecs_t& vec, arglist_t* arg) { - printf("\t" WEB_DOC_DIR "/fmt_%s.html", vec->name); + printf("\t" WEB_DOC_DIR "/fmt_%s.html", vec.name); if (arg) { - printf("#fmt_%s_o_%s",vec->name, arg->argstring); + printf("#fmt_%s_o_%s",vec.name, arg->argstring); } printf("\n"); } static void -disp_v3(const vecs_t* vec) +disp_v3(const vecs_t& vec) { disp_help_url(vec, nullptr); - for (auto ap = vec->vec->args; ap && ap->argstring; ap++) { + for (auto ap = vec.vec->args; ap && ap->argstring; ap++) { if (!(ap->argtype & ARGTYPE_HIDDEN)) { printf("option\t%s\t%s\t%s\t%s\t%s\t%s\t%s", - vec->name, + vec.name, ap->argstring, ap->helpstring, name_option(ap->argtype), @@ -1660,115 +1625,109 @@ disp_v3(const vecs_t* vec) void disp_formats(int version) { - vecs_t** svp; - vecs_t* vec; - int vc = 0; + const auto svp = sort_and_unify_vecs(); switch (version) { - case 0: - case 1: - case 2: - case 3: - svp = sort_and_unify_vecs(&vc); - for (int i = 0; i 0) { - disp_v1(vec->vec->type); + disp_v1(vec.vec->type); } else { - if (vec->vec->type == ff_type_internal) { + if (vec.vec->type == ff_type_internal) { continue; } } if (version >= 2) { - disp_v2(vec->vec); + disp_v2(vec.vec); } - printf("%s\t%s\t%s%s%s\n", vec->name, - !vec->extensions.isEmpty() ? CSTR(vec->extensions) : "", - CSTR(vec->desc), - version >= 3 ? "\t" : "", - version >= 3 ? vec->parent : ""); + printf("%s\t%s\t%s%s%s\n", vec.name, + !vec.extensions.isEmpty() ? CSTR(vec.extensions) : "", + CSTR(vec.desc), + version >= 3 ? "\t" : "", + version >= 3 ? vec.parent : ""); if (version >= 3) { disp_v3(vec); } } - xfree(svp); break; - default: + default: ; } } static bool -validate_vec(const vecs_t* vec) +validate_vec(const vecs_t& vec) { bool ok = true; - if (!((vec->vec->cap[0]|vec->vec->cap[1]|vec->vec->cap[2]) & ff_cap_write)) { - if (vec->vec->wr_init != nullptr) { - printf("ERROR no write capability but non-null wr_init %s\n", vec->name); + if (!((vec.vec->cap[0]|vec.vec->cap[1]|vec.vec->cap[2]) & ff_cap_write)) { + if (vec.vec->wr_init != nullptr) { + printf("ERROR no write capability but non-null wr_init %s\n", vec.name); ok = false; } } - if (!((vec->vec->cap[0]|vec->vec->cap[1]|vec->vec->cap[2]) & ff_cap_read)) { - if (vec->vec->rd_init != nullptr) { - printf("ERROR no read capbility but non-null rd_init %s\n", vec->name); + if (!((vec.vec->cap[0]|vec.vec->cap[1]|vec.vec->cap[2]) & ff_cap_read)) { + if (vec.vec->rd_init != nullptr) { + printf("ERROR no read capbility but non-null rd_init %s\n", vec.name); ok = false; } } - if ((vec->vec->cap[0]|vec->vec->cap[1]|vec->vec->cap[2]) & ff_cap_write) { - if (vec->vec->wr_init == nullptr) { - printf("ERROR write capability but null wr_init %s\n", vec->name); + if ((vec.vec->cap[0]|vec.vec->cap[1]|vec.vec->cap[2]) & ff_cap_write) { + if (vec.vec->wr_init == nullptr) { + printf("ERROR write capability but null wr_init %s\n", vec.name); ok = false; } } - if ((vec->vec->cap[0]|vec->vec->cap[1]|vec->vec->cap[2]) & ff_cap_read) { - if (vec->vec->rd_init == nullptr) { - printf("ERROR read capability but null rd_init %s\n", vec->name); + if ((vec.vec->cap[0]|vec.vec->cap[1]|vec.vec->cap[2]) & ff_cap_read) { + if (vec.vec->rd_init == nullptr) { + printf("ERROR read capability but null rd_init %s\n", vec.name); ok = false; } } - if (vec->vec->wr_init != nullptr) { - if (vec->vec->write == nullptr) { - printf("ERROR nonnull wr_init but null write %s\n", vec->name); + if (vec.vec->wr_init != nullptr) { + if (vec.vec->write == nullptr) { + printf("ERROR nonnull wr_init but null write %s\n", vec.name); ok = false; } - if (vec->vec->wr_deinit == nullptr) { - printf("ERROR nonnull wr_init but null wr_deinit %s\n", vec->name); + if (vec.vec->wr_deinit == nullptr) { + printf("ERROR nonnull wr_init but null wr_deinit %s\n", vec.name); ok = false; } } - if (vec->vec->wr_init == nullptr) { - if (vec->vec->write != nullptr) { - printf("ERROR null wr_init with non-null write %s\n", vec->name); + if (vec.vec->wr_init == nullptr) { + if (vec.vec->write != nullptr) { + printf("ERROR null wr_init with non-null write %s\n", vec.name); ok = false; } - if (vec->vec->wr_deinit != nullptr) { - printf("ERROR null wr_init with non-null wr_deinit %s\n", vec->name); + if (vec.vec->wr_deinit != nullptr) { + printf("ERROR null wr_init with non-null wr_deinit %s\n", vec.name); ok = false; } } - if (vec->vec->rd_init != nullptr) { - if (vec->vec->read == nullptr) { - printf("ERROR nonnull rd_init but null read %s\n", vec->name); + if (vec.vec->rd_init != nullptr) { + if (vec.vec->read == nullptr) { + printf("ERROR nonnull rd_init but null read %s\n", vec.name); ok = false; } - if (vec->vec->rd_deinit == nullptr) { - printf("ERROR nonnull rd_init but null rd_deinit %s\n", vec->name); + if (vec.vec->rd_deinit == nullptr) { + printf("ERROR nonnull rd_init but null rd_deinit %s\n", vec.name); ok = false; } } - if (vec->vec->rd_init == nullptr) { - if (vec->vec->read != nullptr) { - printf("ERROR null rd_init with non-null read %s\n", vec->name); + if (vec.vec->rd_init == nullptr) { + if (vec.vec->read != nullptr) { + printf("ERROR null rd_init with non-null read %s\n", vec.name); ok = false; } - if (vec->vec->rd_deinit != nullptr) { - printf("ERROR null rd_init with non-null rd_deinit %s\n", vec->name); + if (vec.vec->rd_deinit != nullptr) { + printf("ERROR null rd_init with non-null rd_deinit %s\n", vec.name); ok = false; } } @@ -1780,10 +1739,8 @@ int validate_formats() { bool ok = true; - const vecs_t* vec = vec_list; - while (vec->vec) { + for (const auto& vec : vec_list) { ok = validate_vec(vec) && ok; - vec++; } return ok? 0 : 1; -- 2.30.2